home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Reference / the cmsp digests ('94-'97) / csmp digest Vol 3 No 056 < prev    next >
Encoding:
Internet Message Format  |  1997-05-06  |  55.5 KB  |  [TEXT/R*ch]

  1. From: pottier@clipper.ens.fr (Francois Pottier)
  2. Subject: csmp-digest-v3-056
  3. Date: Sat, 10 Sep 1994 13:05:29 +0200 (MET DST)
  4.  
  5. C.S.M.P. Digest             Sat, 10 Sep 94       Volume 3 : Issue 56
  6.  
  7. Today's Topics:
  8.  
  9.         A tool I could REALLY use, written it?
  10.         Async FileMgr Calls
  11.         Future of ASLM
  12.         Review of PowerMac devtools available
  13.         SetDialogDefaultItem() not doing anything!
  14.         Trouble making floating windows work with modeless dialogs
  15.  
  16.  
  17.  
  18. The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
  19. (pottier@clipper.ens.fr).
  20.  
  21. The digest is a collection of article threads from the internet newsgroup
  22. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  23. regularly and want an archive of the discussions.  If you don't know what a
  24. newsgroup is, you probably don't have access to it.  Ask your systems
  25. administrator(s) for details.  If you don't have access to news, you may
  26. still be able to post messages to the group by using a mail server like
  27. anon.penet.fi (mail help@anon.penet.fi for more information).
  28.  
  29. Each issue of the digest contains one or more sets of articles (called
  30. threads), with each set corresponding to a 'discussion' of a particular
  31. subject.  The articles are not edited; all articles included in this digest
  32. are in their original posted form (as received by our news server at
  33. nef.ens.fr).  Article threads are not added to the digest until the last
  34. article added to the thread is at least two weeks old (this is to ensure that
  35. the thread is dead before adding it to the digest).  Article threads that
  36. consist of only one message are generally not included in the digest.
  37.  
  38. The digest is officially distributed by two means, by email and ftp.
  39.  
  40. If you want to receive the digest by mail, send email to listserv@ens.fr
  41. with no subject and one of the following commands as body:
  42.     help                        Sends you a summary of commands
  43.     subscribe csmp-digest Your Name    Adds you to the mailing list
  44.     signoff csmp-digest            Removes you from the list
  45. Once you have subscribed, you will automatically receive each new
  46. issue as it is created.
  47.  
  48. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
  49. Questions related to the ftp site should be directed to
  50. scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
  51. digest are available there.
  52.  
  53. Also, the digests are available to WAIS users.  To search back issues
  54. with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
  55. http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
  56.  
  57.  
  58. -------------------------------------------------------
  59.  
  60. >From Chris Russo <chris@sonicsys.com>
  61. Subject: A tool I could REALLY use, written it?
  62. Date: 24 Aug 1994 16:57:56 GMT
  63. Organization: Sonic Systems, Inc.
  64.  
  65. While tracking down a nasty memory leak yesterday, I thought of something that
  66. would have been REALLY helpful.  What if I patched NewHandle() so that
  67. whenever it was called it would traipse over to the end of my routine and grab
  68. the Debugger info, then tacked it onto the rear of the handle?
  69.  
  70. That way, I could look at all of those loose memory fragments from ZoneRanger
  71. and determine instantly from where they had been allocated.
  72.  
  73. I started working on the thing yesterday, and spent a couple of hours on it.
  74. I wrote patches for NewHandle(), GetHandleSize(), and SetHandleSize().  Those
  75. last two would naturally have to be patched to make the debugging info
  76. transparent to the calling application.
  77.  
  78. Unfortunately, the routines aren't quite working and tend to crash.  More
  79. unfortunately, I don't have the time to keep working on them. :-(
  80.  
  81. If anyone's already written such a patch, <whoops> please let me know how it
  82. went and if I could have it.
  83.  
  84. If anyone would like to take this idea and run with it, by all means do so. 
  85. You can even have the source that I started.  There might be some issues
  86. involving the application's trap dispatch table that I'm not dealing with
  87. properly.  I've never really taken the time to learn that much about it, but
  88. would be happy to learn where I went awry.
  89.  
  90. btw, I have seen the leaks dcmd and don't really like to use it much.  From
  91. ZoneRanger, I can usually tell which memory blocks are useless, but it's hard
  92. to correlate those to the ones captured in leaks.  On top of that, leaks
  93. crashes my version of TMON.
  94.  
  95. Once again, if anyone wants to continue my effort, let me know.
  96.  
  97. - ------------------------------------------------------------------------
  98. Chris Russo                      Macintosh Programmer
  99. Sonic Systems, Inc.              (408) 736-1900 #107
  100. chris@sonicsys.com               NEVER respond to flame bait!
  101.  
  102. +++++++++++++++++++++++++++
  103.  
  104. >From onyxtech@aol.com (OnyxTech)
  105. Date: 26 Aug 1994 17:43:03 -0400
  106. Organization: America Online, Inc. (1-800-827-6364)
  107.  
  108. In article <33fu6k$f5s@news.internex.net>, Chris Russo
  109. <chris@sonicsys.com> writes:
  110.  
  111. >While tracking down a nasty memory leak yesterday, I thought of
  112. >something that would have been REALLY helpful.  What if I patched
  113. >NewHandle() so that whenever it was called it would traipse over to
  114. >the end of my routine and grab the Debugger info, then tacked it onto
  115. >the rear of the handle?
  116. >That way, I could look at all of those loose memory fragments from
  117. >ZoneRanger and determine instantly from where they had been allocated.
  118.  
  119. Mmmm.  There is a version of QC(tm) that has similar leaks detection (you
  120. can use sym files as well) that will follow a native PowerPC upgrade ahead
  121. of it in the pipeline.  We are working on graphical representation of heap
  122. allocations and deletions and hope to create some sort of published
  123. interface so tools like ZoneRanger can use our data to represent more
  124. information to users.  After all, why should we re-create ZoneRanger type
  125. utilities when they've already done all the work.  We just need to help
  126. them get at more information.
  127.  
  128. If you'd like me to keep you (and whomever else is reading this) abreast
  129. of this new version of QC, drop us a line at 'onyxtech@aol.com'.
  130.  
  131. dEVoN Hubbard
  132. Onyx Technology
  133.  
  134. +++++++++++++++++++++++++++
  135.  
  136. >From h+@nada.kth.se (Jon W{tte)
  137. Date: Sat, 27 Aug 1994 15:52:17 +0200
  138. Organization: Royal Institute of Something or other
  139.  
  140. In article <33fu6k$f5s@news.internex.net>,
  141. Chris Russo <chris@sonicsys.com> wrote:
  142.  
  143. >While tracking down a nasty memory leak yesterday, I thought of something that
  144. >would have been REALLY helpful.  What if I patched NewHandle() so that
  145. >whenever it was called it would traipse over to the end of my routine and grab
  146. >the Debugger info, then tacked it onto the rear of the handle?
  147. >
  148. >That way, I could look at all of those loose memory fragments from ZoneRanger
  149. >and determine instantly from where they had been allocated.
  150.  
  151. It's easier to just install the "leaks" MacsBug dcmd. I don't 
  152. know whether it will still work with the new memroy manager 
  153. though. Anyone else know?
  154.  
  155. Another thing you can do is to replace all your calls to 
  156. NewHandle() etc with MyNewHandle() and have non-patches that 
  157. did the tracking work; you could even define MyNewHandle to 
  158. pass source file and line number information using __FILE__ and 
  159. __LINE__. Then when you compile the release version, you just 
  160. define MyNewHandle() to NewHandle().
  161.  
  162. This is great for validating memory as well; you can have a 
  163. validation routine that traverses all of your dynamically 
  164. allocated memory and checks it against a list you keep; if 
  165. something's not checked on the list, you have a leak. If a 
  166. pointer/handle is not on the list, you have a dangling 
  167. pointer/handle.
  168.  
  169. Cheers,
  170.  
  171.                 / h+
  172.  
  173.  
  174. --
  175.   Jon Wätte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
  176.     Not speaking for IBM.
  177.  
  178.  
  179. ---------------------------
  180.  
  181. >From chris-b@cs.auckland.ac.nz (Chris Burns)
  182. Subject: Async FileMgr Calls
  183. Date: Sat, 20 Aug 1994 00:58:02 +1200
  184. Organization: AucklandUniversity:ComputerScience:HMU
  185.  
  186. Hi All,
  187.  
  188. I've been looking into using async file manager calls, so I started
  189. experimenting with an easy one, an indexed _PBHGetVInfoAsync call until
  190. the error returned is nsvErr (no-such-volume: -35). This works perfectly
  191. using sync calls. Things aren't so rosy on the async front tho'.
  192.  
  193. Being in a PowerPC friendly kind of mood (and running on a PM8100/80), I
  194. thought "cool, I'll use UPPs for my completion routine specifiers, and
  195. compile a fat app". This aspect is fine, and in fact, the PowerPC native
  196. version (MW C/C++ PPC 1.01 DR/3.5) is the one that works correctly. The
  197. 68K version however, does not work. The _PBHGetVInfoAsync call returns all
  198. kinds of bogus values instead of nice file manager errors.
  199.  
  200. Here's the entire code:
  201.  
  202.  
  203. ////////////////////////////////////////////
  204. // Chris Burns  ©August 1994
  205. ////////////////////////////////////////////
  206.  
  207. #include <Files.h>
  208.  
  209. ////////////////////////////////////////////
  210.  
  211. typedef struct
  212. {
  213.     HVolumeParam    PB;
  214.     Str255          VolName;
  215.     long            AppA5;
  216. }
  217. VolPBRec,*VolPBPtr;
  218.  
  219. ////////////////////////////////////////////
  220.  
  221. short           gNumDrives;
  222. volatile short  gNumDrivesDone;
  223.  
  224. ////////////////////////////////////////////
  225.  
  226. IOCompletionUPP     gCompletionProcUPP;
  227.  
  228. #if USES68KINLINES
  229. #pragma parameter CompletionProc(__A0)
  230. #endif
  231.  
  232. pascal void CompletionProc(HParmBlkPtr HPB)
  233. {
  234. long SavedA5 = SetA5(((VolPBPtr)HPB)->AppA5);
  235.  
  236.     gNumDrivesDone++;
  237.     DebugStr(((VolPBPtr)HPB)->VolName);
  238.  
  239.     SetA5(SavedA5);
  240. }
  241.  
  242. ////////////////////////////////////////////
  243.  
  244. void main(void)
  245. {
  246. OSErr               Err;
  247. VolPBPtr            VPB;
  248.  
  249.     gNumDrives = 0;
  250.     gNumDrivesDone = 0;
  251.     gCompletionProcUPP = NewIOCompletionProc(CompletionProc);
  252.  
  253.     Err = noErr;
  254.  
  255.     while (Err != nsvErr)
  256.     {
  257.         gNumDrives++;
  258.     
  259.         VPB = (VolPBPtr)NewPtrClear(sizeof(VolPBRec));
  260.         if ((VPB == nil) || (MemError() != noErr))
  261.             DebugStr("\pMain: _NewPtrClear(VPB) FAILED");
  262.         
  263.         VPB->PB.ioCompletion = gCompletionProcUPP;
  264.         VPB->PB.ioVolIndex = gNumDrives;
  265.         VPB->PB.ioNamePtr = VPB->VolName;
  266.         VPB->PB.ioVRefNum = 0;
  267.         VPB->AppA5 = SetCurrentA5();
  268.  
  269.         Err = PBHGetVInfoAsync((HParmBlkPtr)VPB);
  270.  
  271.         switch (Err)
  272.         {
  273.             case noErr:
  274.                 break;
  275.  
  276.             case nsvErr:
  277.                 continue;
  278.  
  279.             default:
  280.                 DebugStr("\p_PBHGetVInfoAsync FAILED");
  281.                 break;
  282.         }
  283.     }
  284.  
  285.     while (gNumDrivesDone != gNumDrives);
  286.  
  287.     DisposeRoutineDescriptor(gCompletionProcUPP);
  288. }
  289.  
  290. ////////////////////////////////////////////
  291.  
  292. The:
  293.  
  294. #if USES68KINLINES
  295. #pragma parameter CompletionProc(__A0)
  296. #endif
  297.  
  298. bit was necessary for the 68K version to realize the param block ptr was
  299. in A0 rather than on the stack. I just grabbed it from one of the
  300. Universal Headers because it looked right. It seems to work, and the asm
  301. looks right.
  302.  
  303. The problem seems to be in my CompletionProc. Whatever value D0.w is upon
  304. exit, comes out as the original Err = PBHGetVInfoAsync(); This shouldn't
  305. be so because that error simply tells me if the request was queued ok. For
  306. file manager completion routines THINK Ref 2.0 says "Save and restore all
  307. CPU registers except A0,A1, and D0-D2". My code seems to do this yet
  308. doesn't run correctly.
  309.  
  310. Here's the 68K asm:
  311.  
  312. Hunk:   Kind=HUNK_GLOBAL_CODE  Name="COMPLETIONPROC"(4)  Size=64
  313. 00000000: 4E56 FFF8          LINK      A6,#$FFF8
  314. 00000004: 2D48 FFF8          MOVE.L    A0,$FFF8(A6)
  315. 00000008: 206E FFF8          MOVEA.L   $FFF8(A6),A0
  316. 0000000C: 2028 017A          MOVE.L    $017A(A0),D0
  317. 00000010: C18D               EXG       D0,A5
  318. 00000012: 2D40 FFFC          MOVE.L    D0,$FFFC(A6)
  319. 00000016: 526D 0000          ADDQ.W    #$1,gNumDrivesDone
  320. 0000001A: 206E FFF8          MOVEA.L   $FFF8(A6),A0
  321. 0000001E: 4868 007A          PEA       $007A(A0)
  322. 00000022: ABFF               _DebugStr
  323. 00000024: 202E FFFC          MOVE.L    $FFFC(A6),D0
  324. 00000028: C18D               EXG       D0,A5
  325. 0000002A: 4E5E               UNLK      A6
  326. 0000002C: 4E75               RTS
  327. 0000002E: 8E43 4F4D 504C     DC.B      $80+$0E, 'COMPLETIONPROC', $00
  328.           4554 494F 4E50 
  329.           524F 4300      
  330. 0000003E: 0000           
  331.  
  332. Any help, flames, guidance etc greatly appreciated.
  333.  
  334. Thanks In Advance,
  335.  
  336. Chris B
  337. - ---------------------------------------------------------------------
  338. NewZealand:AucklandUniversity:ComputerScience:HyperMediaUnit:ChrisBurns
  339. Internet: chris-b@cs.auckland.ac.nz
  340. Phone:    +64 9 373-7599 x6194
  341. Fax:      +64 9 373-7453                         Async, therefore I am.
  342. - ---------------------------------------------------------------------
  343.  
  344. +++++++++++++++++++++++++++
  345.  
  346. >From h+@nada.kth.se (Jon W{tte)
  347. Date: Fri, 19 Aug 1994 22:27:16 +0200
  348. Organization: Royal Institute of Something or other
  349.  
  350. In article <chris-b-2008940058020001@hmu7.cs.aukuni.ac.nz>,
  351. chris-b@cs.auckland.ac.nz (Chris Burns) wrote:
  352.  
  353. >version (MW C/C++ PPC 1.01 DR/3.5) is the one that works correctly. The
  354. >68K version however, does not work. The _PBHGetVInfoAsync call returns all
  355. >kinds of bogus values instead of nice file manager errors.
  356.  
  357. That's because you're testing the return value of an asynchronous
  358. call. You're not supposed to do that, since there's no error to
  359. return there yet; instead you're supposed to test ioResult in the
  360. completion proc, or poll ioResult until it's not 1.
  361.  
  362. Cheers,
  363.  
  364.                 / h+
  365.  
  366.  
  367. --
  368.   Jon Wätte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
  369.  
  370. "TextEdit does everything right."
  371.     — Jon W{tte
  372.  
  373.  
  374. +++++++++++++++++++++++++++
  375.  
  376. >From chris-b@cs.auckland.ac.nz (Chris Burns)
  377. Date: Sun, 21 Aug 1994 18:19:12 +1200
  378. Organization: AucklandUniversity:ComputerScience:HMU
  379.  
  380. In article <9668AA7AE244.44E5E@klkmac004.nada.kth.se>, h+@nada.kth.se (Jon
  381. W{tte) wrote:
  382.  
  383. > In article <chris-b-2008940058020001@hmu7.cs.aukuni.ac.nz>,
  384. > chris-b@cs.auckland.ac.nz (Chris Burns) wrote:
  385. > >version (MW C/C++ PPC 1.01 DR/3.5) is the one that works correctly. The
  386. > >68K version however, does not work. The _PBHGetVInfoAsync call returns all
  387. > >kinds of bogus values instead of nice file manager errors.
  388. > That's because you're testing the return value of an asynchronous
  389. > call. You're not supposed to do that, since there's no error to
  390. > return there yet; instead you're supposed to test ioResult in the
  391. > completion proc, or poll ioResult until it's not 1.
  392.  
  393. Sorry Jon, I don't buy it.
  394.  
  395. (I'm assuming that IM-IV Chpt 19 [File Manager] is still valid because it
  396. documents the low-level file manager routines; I havn't looked at
  397. NIM:Files)
  398.  
  399. Check out IM-IV Pg 119:
  400.  
  401. "Routines that are executed asynchronously return control to the calling
  402. program with the result code noErr as soon as the call is placed in the
  403. file I/O queue. This isn't an indication of successful call completion,
  404. but simply indicates that the call was successfully queued."
  405.  
  406. This is the case with nearly all async calls, they return a file manager
  407. error to the calling program (typically "noErr", but possibly "paramErr"
  408. or others), and then the real error somewhere in the param block (often
  409. also in D0) at completion proc time. These two errors should not be
  410. related in any way. The fact that D0 = $stuvwxyz upon exit of the
  411. completion proc should not mean that the calling code receives an error of
  412. $wxyz (D0.w).
  413.  
  414. IM-IV Pg 119:
  415.  
  416. "Warning: Completion routines are executed at interrupt level and must
  417. preserve all registers other than A0,A1, and D0-D2."
  418.  
  419. Surely this means my completion routine code can do what it wants with
  420. these regs without affecting anything.
  421.  
  422. IM-IV Pg 119:
  423.  
  424. "When your completion routine is called, register A0 points to the
  425. parameter block of the asynchronous call and register D0 contains the
  426. result code."
  427.  
  428. I read this to mean that these were "read-only" values (changes are not
  429. propagated back to calling code). I based this upon the fact that the
  430. completion proc may be called _well_ after the _PBHGetVInfo call. A remote
  431. file system such as an AppleShare volume will definitely be this way for
  432. mnay types of calls.
  433.  
  434.  
  435. I have kind-of solved this problem, but not to my satisfaction. If I save
  436. and restore the scratch regs (A0,A1, and D0-D2) the thing works properly.
  437. However, I don't think I should need to do this, and besides, its real
  438. ugly.
  439.  
  440. #if USES68KINLINES
  441. asm....
  442. #endif
  443.  
  444. yuck!
  445.  
  446. Any more ideas would be wonderful.
  447.  
  448. Thanks Heaps In Advance,
  449.  
  450. Chris B
  451. - ---------------------------------------------------------------------
  452. NewZealand:AucklandUniversity:ComputerScience:HyperMediaUnit:ChrisBurns
  453. Internet: chris-b@cs.auckland.ac.nz
  454. Phone:    +64 9 373-7599 x6194
  455. Fax:      +64 9 373-7453                         Async, therefore I am.
  456. - ---------------------------------------------------------------------
  457.  
  458. +++++++++++++++++++++++++++
  459.  
  460. >From Jaeger@fquest.com (Brian Stern)
  461. Date: 21 Aug 1994 14:39:41 GMT
  462. Organization: The University of Texas at Austin, Austin, Texas
  463.  
  464. In article <chris-b-2008940058020001@hmu7.cs.aukuni.ac.nz>,
  465. chris-b@cs.auckland.ac.nz wrote:
  466.  
  467. > Hi All,
  468. > I've been looking into using async file manager calls, so I started
  469. > experimenting with an easy one, an indexed _PBHGetVInfoAsync call until
  470. > the error returned is nsvErr (no-such-volume: -35). This works perfectly
  471. > using sync calls. Things aren't so rosy on the async front tho'.
  472. > Being in a PowerPC friendly kind of mood (and running on a PM8100/80), I
  473. > thought "cool, I'll use UPPs for my completion routine specifiers, and
  474. > compile a fat app". This aspect is fine, and in fact, the PowerPC native
  475. > version (MW C/C++ PPC 1.01 DR/3.5) is the one that works correctly. The
  476. > 68K version however, does not work. The _PBHGetVInfoAsync call returns all
  477. > kinds of bogus values instead of nice file manager errors.
  478. > Here's the entire code:
  479. > #if USES68KINLINES
  480. > #pragma parameter CompletionProc(__A0)
  481. > #endif
  482. > pascal void CompletionProc(HParmBlkPtr HPB)
  483. > {
  484. > long SavedA5 = SetA5(((VolPBPtr)HPB)->AppA5);
  485. >     gNumDrivesDone++;
  486. >     DebugStr(((VolPBPtr)HPB)->VolName);
  487. >     SetA5(SavedA5);
  488. > }
  489. > Chris B
  490. > -----------------------------------------------------------------------
  491. > NewZealand:AucklandUniversity:ComputerScience:HyperMediaUnit:ChrisBurns
  492. > Internet: chris-b@cs.auckland.ac.nz
  493. > Phone:    +64 9 373-7599 x6194
  494. > Fax:      +64 9 373-7453                         Async, therefore I am.
  495. > -----------------------------------------------------------------------
  496.  
  497. So why not change it to this:
  498.  
  499. #if USES68KINLINES
  500. #pragma parameter __D0 CompletionProc(__A0)
  501. #endif
  502.  
  503. pascal OSErr CompletionProc(HParmBlkPtr HPB)
  504. {
  505. long SavedA5 = SetA5(((VolPBPtr)HPB)->AppA5);
  506.  
  507.     gNumDrivesDone++;
  508.     DebugStr(((VolPBPtr)HPB)->VolName);
  509.  
  510.     SetA5(SavedA5);
  511.  
  512.     return HPB->ioResult;
  513.  
  514. }
  515.  
  516. No Assembly Required.
  517.  
  518. My reading of the passages in IM-IV that you quoted seems ambiguous about
  519. whether or not a completion routine returns a result in DO.  My first
  520. guess would have been no.
  521.  
  522. BTW, Use of the #pragma parameter in this way in MW works differently from
  523. Think C.  In Think you can only use #pragma parameter for inline calls. 
  524. This means that it's only useful for routines that you're calling, not for
  525. cases where your routines are called with parameters in registers.  So
  526. when compiling your CompletionProc with Think C, the compiler ignores the
  527. #pragma parameter and assumes that HPB was passed on the stack.  Oh well 
  528. :-(
  529.  
  530. -- 
  531. Brian  Stern  :-{)}
  532. Jaeger@fquest.com
  533.  
  534. +++++++++++++++++++++++++++
  535.  
  536. >From resnick@uiuc.edu (Pete Resnick)
  537. Date: Sun, 21 Aug 1994 13:02:57 -0500
  538. Organization: University of Illinois at Urbana-Champaign
  539.  
  540. In article <9668AA7AE244.44E5E@klkmac004.nada.kth.se>, h+@nada.kth.se (Jon
  541. W{tte) wrote:
  542.  
  543. >That's because you're testing the return value of an asynchronous
  544. >call. You're not supposed to do that, since there's no error to
  545. >return there yet; instead you're supposed to test ioResult in the
  546. >completion proc, or poll ioResult until it's not 1.
  547.  
  548. No, you're wrong. Inside Macintosh: Files, page 2-6 is quite explicit:
  549.  
  550.     Routines that are executed asynchronously return control to your
  551.     application with the result code noErr as soon as the call is placed in
  552.     the file I/O queue. Return of control does not signal successful
  553.     completion of the call, but simply successful queuing of the request.
  554.  
  555. You could plausibly get back an error if for some reason the Device
  556. Manager determined that the call could not be queued (a screwy refNum or
  557. the like). You are perfectly correct (though maybe using a little
  558. overkill) in checking the return code from an asynchronous routine. The
  559. problem lies somewhere else.
  560.  
  561. pr
  562. -- 
  563. Pete Resnick        (...so what is a mojo, and why would one be rising?)
  564. Doctoral Student - Philosophy Department, Gregory Hall, UIUC
  565. System manager - Cognitive Science Group, Beckman Institute, UIUC
  566. Internet: resnick@uiuc.edu
  567.  
  568. +++++++++++++++++++++++++++
  569.  
  570. >From benh@fdn.org (Benjamin Herrenschmidt)
  571. Date: Mon, 22 Aug 94 11:52:45 +0100
  572. Organization: (none)
  573.  
  574.  
  575.  
  576. >>That's because you're testing the return value of an asynchronous
  577. >>call. You're not supposed to do that, since there's no error to
  578. >>return there yet; instead you're supposed to test ioResult in the
  579. >>completion proc, or poll ioResult until it's not 1.
  580. >
  581. >No, you're wrong. Inside Macintosh: Files, page 2-6 is quite explicit:
  582. >
  583. >    Routines that are executed asynchronously return control to your
  584. >    application with the result code noErr as soon as the call is placed in
  585. >    the file I/O queue. Return of control does not signal successful
  586. >    completion of the call, but simply successful queuing of the request.
  587. >
  588. >You could plausibly get back an error if for some reason the Device
  589. >Manager determined that the call could not be queued (a screwy refNum or
  590. >the like). You are perfectly correct (though maybe using a little
  591. >overkill) in checking the return code from an asynchronous routine. The
  592. >problem lies somewhere else.
  593.  
  594. I remember something about async File Mgr. calls : unlike device manager
  595. calls, File Manager calls ALWAYS calls the completion routine to handle
  596. the result code, and the result of the async call itself MAY be garbage,
  597. event if something is wrong with the queue. The result code you should
  598. use is the one returned to the completion routine (or in the ioResult
  599. field of the paramblock)
  600.  
  601. I think i read this in a technote or a Q&A... 
  602.  
  603. BenH.
  604.  
  605. +++++++++++++++++++++++++++
  606.  
  607. >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
  608. Date: 23 Aug 94 18:05:13 +1200
  609. Organization: University of Waikato, Hamilton, New Zealand
  610.  
  611. In article <chris-b-2108941819120001@hmu7.cs.aukuni.ac.nz>, chris-b@cs.auckland.ac.nz (Chris Burns) writes:
  612. > In article <9668AA7AE244.44E5E@klkmac004.nada.kth.se>, h+@nada.kth.se (Jon
  613. > W{tte) wrote:
  614. >
  615. >> In article <chris-b-2008940058020001@hmu7.cs.aukuni.ac.nz>,
  616. >> chris-b@cs.auckland.ac.nz (Chris Burns) wrote:
  617. >>
  618. >> That's because you're testing the return value of an asynchronous
  619. >> call. You're not supposed to do that, since there's no error to
  620. >> return there yet; instead you're supposed to test ioResult in the
  621. >> completion proc, or poll ioResult until it's not 1.
  622. >
  623. > Sorry Jon, I don't buy it.
  624. >
  625. > (I'm assuming that IM-IV Chpt 19 [File Manager] is still valid because it
  626. > documents the low-level file manager routines; I havn't looked at
  627. > NIM:Files)
  628. >
  629. > Check out IM-IV Pg 119:
  630. >
  631. > "Routines that are executed asynchronously return control to the calling
  632. > program with the result code noErr as soon as the call is placed in the
  633. > file I/O queue. This isn't an indication of successful call completion,
  634. > but simply indicates that the call was successfully queued."
  635.  
  636. There is a technote somewhere which corrects this. Basically, you shouldn't
  637. bother checking the immediate return code from _any_ async call. I recently
  638. got burned with this doing async sound recording: my call to SPBRecord worked
  639. fine everywhere _except_ on a 500-series PowerBook, and then only when I
  640. invoked a combination of certain other recording options at the same time.
  641.  
  642. There is one situation where you should be careful about polling ioResult
  643. (And I'm not talking about being stupid, sitting in a tight loop at interrupt
  644. level, blocking the completion of the call you're polling for!): the PPC
  645. Toolbox. In System 7.0, the PPC Toolbox sets ioResult some time before it
  646. dequeues the parameter block from its request queue. This means if you have
  647. an interrupt routine that periodically checks the ioResult from a PPC Toolbox
  648. request, and assumes the parameter block can be reused the moment it goes 0
  649. or negative, you could be in for a crash. If you specify a completion routine,
  650. then the parameter block can be safely reused when this routine is called.
  651.  
  652. I understand this might be fixed in later Systems, but I'm not sure which ones.
  653. If Jim Luther is reading this, he might be able to update us...
  654.  
  655. Lawrence D'Oliveiro                       fone: +64-7-856-2889
  656. Info & Tech Services Division              fax: +64-7-838-4066
  657. University of Waikato            electric mail: ldo@waikato.ac.nz
  658. Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
  659.  
  660. +++++++++++++++++++++++++++
  661.  
  662. >From chris-b@cs.auckland.ac.nz (Chris Burns)
  663. Date: Wed, 24 Aug 1994 12:47:36 +1200
  664. Organization: AucklandUniversity:ComputerScience:HMU
  665.  
  666. In article <Jaeger-2108940941410001@slip-1-88.ots.utexas.edu>,
  667. Jaeger@fquest.com (Brian Stern) wrote:
  668.  
  669. > So why not change it to this:
  670. > #if USES68KINLINES
  671. > #pragma parameter __D0 CompletionProc(__A0)
  672. > #endif
  673. > pascal OSErr CompletionProc(HParmBlkPtr HPB)
  674. > {
  675. > long SavedA5 = SetA5(((VolPBPtr)HPB)->AppA5);
  676. >     gNumDrivesDone++;
  677. >     DebugStr(((VolPBPtr)HPB)->VolName);
  678. >     SetA5(SavedA5);
  679. >     return HPB->ioResult;
  680. > }
  681. > No Assembly Required.
  682.  
  683. Yeah, good idea Brian. This actually works on both platforms and does not
  684. use any asm. Thanks for the idea, I'll end up using this.
  685.  
  686. It should not be required tho'. Apple docs clearly state that D0 doesn't
  687. have to be save/restored and don't say the error should be returned in D0
  688. either (in fact this cannot be the case because the completion proc could
  689. potentially execute _well after_ the original error has been returned.
  690. Maybe this call cannot be done truely async?
  691.  
  692. Thanks Again,
  693.  
  694. Chris B
  695. - ---------------------------------------------------------------------
  696. NewZealand:AucklandUniversity:ComputerScience:HyperMediaUnit:ChrisBurns
  697. Internet: chris-b@cs.auckland.ac.nz
  698. Phone:    +64 9 373-7599 x6194
  699. Fax:      +64 9 373-7453                         Async, therefore I am.
  700. - ---------------------------------------------------------------------
  701.  
  702. +++++++++++++++++++++++++++
  703.  
  704. >From Clinton Bauder <gecko1@applelink.apple.com>
  705. Date: Wed, 24 Aug 1994 21:02:10 GMT
  706. Organization: Apple Computer Inc.
  707.  
  708. In article <chris-b-2008940058020001@hmu7.cs.aukuni.ac.nz> Chris Burns,
  709. chris-b@cs.auckland.ac.nz writes:
  710. >
  711. >        Err = PBHGetVInfoAsync((HParmBlkPtr)VPB);
  712. >
  713. >        switch (Err)
  714. >        {
  715. >            case noErr:
  716. >                break;
  717. >
  718. >            case nsvErr:
  719. >                continue;
  720. >
  721. >            default:
  722. >                DebugStr("\p_PBHGetVInfoAsync FAILED");
  723. >                break;
  724. >        }
  725.  
  726. If you are making an async call you have to wait for it to complete.  A
  727. return of noErr from an async call doesn't mean it is done.  I merely
  728. means the PB was correctly filled out and has been accepted (queued) by
  729. the File Mananger.  At some later point it will be completed and the
  730. ioResult field will be updated with the correct result and the completion
  731. routine called.  Your application needs to either poll ioResult (wait til
  732. it is not 1 - which means in progress) or poll some other variable which
  733. is set by the completion routine.  To really take advantage of async IO
  734. you should try and do something with the time in between when you make
  735. the file system call and when ioResult changes to <= noErr.
  736.  
  737. Clinton
  738. - -------------------------------------------------------------
  739. Clinton Bauder        | Opinions expressed are very likely to
  740. SCSI Grunt and Chief  | be entirely different from the official
  741. Herpetoculturist      | party line of Apple Computer Inc.
  742. Apple Computer Inc.   | Support your local herp society.
  743. - -------------------------------------------------------------
  744.  
  745. +++++++++++++++++++++++++++
  746.  
  747. >From jumplong@aol.com (Jump Long)
  748. Date: 26 Aug 1994 01:42:07 -0400
  749. Organization: America Online, Inc. (1-800-827-6364)
  750.  
  751. In article <chris-b-2108941819120001@hmu7.cs.aukuni.ac.nz>,
  752. chris-b@cs.auckland.ac.nz (Chris Burns) writes:
  753.  
  754. >Any more ideas would be wonderful.
  755.  
  756. I responded to Chris via email with this:
  757.  
  758. - ---
  759.  
  760. Chris,
  761.  
  762. You need to get a copy of develop magazine issue #13 and read the article
  763. I wrote called "Asynchronous Routines on the Macintosh".  It answers many
  764. of your current questions and will answer many of the questions you're
  765. going to have in the future :-)  In many cases while writing that article,
  766. I found that Inside Mac was either wrong, or just didn't describe things
  767. completely.
  768.  
  769. Here's some specific information for what you observed.
  770.  
  771. 1) If the File Manager isn't busy when it receives a request (asynchronous
  772. or synchronous), it doesn't queue it - it begins execution of the request
  773. immediately. If the File Manager is busy handling another request, *then*
  774. the request is queued until the all requests before it in the queue have
  775. executed. If the request is a synchronous request, then the system spins
  776. in SyncWait waiting for the synchronous request to be executed. If the
  777. request is an asynchronous request and it is queued, then control is
  778. returned to the caller after the request is queued
  779.  
  780. 2) When the current request is finished executing and the File Manager has
  781. called its completion routine, the File Manager begins excution of the
  782. next request in the queue (if any).
  783.  
  784. 3) Once the File Manager starts executing an asynchronous request, it
  785. doesn't give up control until it is either: a) done handling the request
  786. or b) makes an asynchronous request to a device driver to read or write
  787. block(s) of data and the device driver returns control to the File Manager
  788. while it handles the request asynchronously. The part "while it handles
  789. the request asynchronously" is important because if the driver handles all
  790. requests synchronously (like the old SCSI Manager does), then the File
  791. Manager doesn't get control back from the driver call until it has
  792. completed, and in that case, the File Manager continues with the execution
  793. of the request.
  794.  
  795. So, when you call PBHGetVInfoAsync, if the File Manager isn't busy, it
  796. starts execution of the request immediately.  Since GetVInfo requests
  797. don't cause calls to the driver (unless you pass a working directory
  798. number instead of real volume reference number), there is nothing to stop
  799. the File Manager from completing the request. That's why you're seeing the
  800. request complete immediately.
  801.  
  802. The reason you're seeing the 5 you slam into DO in the completion routine
  803. is that the File Manager uses D0 to return function results to
  804. *synchronous* requests.  With an asynchronous request, you never know what
  805. the real result of the request is until it completes, so the File Manager
  806. sets D0 to 0 when it *starts* execution of the request and doesn't worry
  807. about returning the ioResult value (which is 1 while the call is queued or
  808. executing) to the caller. Here's how we (Apple) recommend making
  809. asychronous File Manager requests (note: Device Manager calls are handled
  810. differently - read the article):
  811.  
  812. /* Make an asynchronous request. */
  813. /* Ignore the function result and look for the */
  814. /* real result when the call completes. */
  815. (void) PBHGetVInfoAsync(&pb);
  816.  
  817. or in Pascal:
  818.  
  819. if (PBHGetVInfoAsync(@pb) <> noErr)
  820.   ; { do nothing, check result at completion }
  821.  
  822. - ---
  823.  
  824. - Jim Luther
  825.  
  826.  
  827. ---------------------------
  828.  
  829. >From bentley@MCS.COM (Mike Bentley)
  830. Subject: Future of ASLM
  831. Date: 13 Aug 1994 17:46:25 -0500
  832. Organization: MCSNet Subscriber Account, Chicago's First Public-Access Internet!
  833.  
  834. What I meant to ask was,
  835. after finally getting something like a shared library manager out for the 680x0
  836. machines, how does ASLM fit into the plan when building a shared library file
  837. with both 680x0 and PowerPC code in it?
  838.  
  839. My guess is that this doesn't happen, that an ASLM library gets a file and the
  840. equivalent code fragment import library (a 'shlb' -- too bad, 'shlp' is funnier)
  841. is a separate file. This probably means that there is some differences in
  842. implementation detail in the source code.
  843.  
  844. -Mike Bentley
  845. Crenelle Inc.
  846.  
  847.  
  848. +++++++++++++++++++++++++++
  849.  
  850. >From garryh@seeding.apple.com (Garry Hornbuckle)
  851. Date: 26 Aug 1994 18:39:45 GMT
  852. Organization: Apple Computer, Inc.
  853.  
  854. In article <32jig1$42k@Mercury.mcs.com>, bentley@MCS.COM (Mike Bentley) wrote:
  855.  
  856. > What I meant to ask was,
  857. > after finally getting something like a shared library manager out for
  858. the 680x0
  859. > machines, how does ASLM fit into the plan when building a shared library file
  860. > with both 680x0 and PowerPC code in it?
  861.  
  862. ==========================================
  863. Macintosh Dynamic Linked Libraries (DLLs)
  864. ==========================================
  865.  
  866. Apple has developed a complete technology solution for shared code, shared
  867. objects, and dynamic linked libraries (DLLs) on the Macintosh. Parts of
  868. this solution are available today, with additional parts becoming
  869. available in the coming months.
  870.  
  871. There are three key components to Macintosh DLL strategy:
  872. • Apple's Shared Library Manager (ASLM),
  873. • Apple's Code Fragment Manager (CFM), and
  874. • IBM's System Object Model (SOM).
  875.  
  876. Here is a brief summary of ASLM, CFM, and SOM ...
  877.  
  878. ASLM
  879. - ----------
  880. Apple Shared Library Manager is the first component of Apple's DLL
  881. solution to be available, and is an integral part of our overall DLL
  882. offering.  ASLM supports shared code libraries for both procedural and
  883. object oriented development efforts. A number of Apple products have
  884. already been based on ASLM, including MacSNMP and the GeoPort
  885. communications pod technology. Third parties such as Microsoft (OLE for
  886. Macintosh), Novell (AppWare), and Aldus have also adopted ASLM to support
  887. their DLL needs.
  888.  
  889. In the future, additonal functionality will be added to the Macintosh
  890. operating system as ASLM libraries, including our next generation
  891. networking, the Open Transport Communications Architecture.
  892.  
  893. ASLM v1.1.2 is the currently shipping release. ASLM v2.0 is under
  894. development, to provide support for native code shared libraries on Power
  895. Macintosh. ASLM 2.x sits on top of (is based on) the Code Fragment
  896. Manager. This work is expected to produce final product in 4Q CY94.
  897.  
  898. As CFM becomes available on 68K Macintosh (see below), a future ASLM
  899. version (2.1) will support CFM on 68K as well, while continuing to support
  900. current 68K-style shared libraries. Thus,  ASLM v2.x will provide
  901. compatibility for ASLM v1.1, v1.1.1, and v1.1.2 applications.
  902.  
  903. ASLM adds higher-level object-oriented capabilities to the environment
  904. that are not a part of the Code Fragment Manager itself. ASLM is the
  905. technology of choice when you:
  906.  
  907. •  need DLLs on 68K today ... ASLM is shipping
  908. •  want simplicity and elegance with C++
  909. •  want a simple but powerful extension mechanism using C, Pascal, or ASM
  910. •  have performance sensitive (i.e., interrupt time) needs like networking
  911. •  want run-time transparent dynamic loading and unloading of code
  912. •  DON'T need transparent access to per-context global data
  913. •  DON'T need to solve the "fragile base class" problem for C++
  914.  
  915. CFM
  916. - ----------
  917. As a second key step in our DLL strategy, Apple has developed a new
  918. foundation layer for dynamic linking on the Macintosh known as the Code
  919. Fragment Manager (CFM). CFM will be a core part of System Software on the
  920. PowerPC Macintosh.
  921.  
  922. CFM is also being developed for the Macintosh on 68K. This work is
  923. expected to produce final product in 1Q CY95.
  924.  
  925. The Code Fragment Manager provides code sharing and dynamic linking, with
  926. features supporting per-context globals. CFM will be fully supported by
  927. development tools on Macintosh.
  928.  
  929. CFM is the best bet when your application:
  930. •  runs on PowerPC Macintosh first, and 68K Macintosh later
  931. •  needs only basic dynamic loading and unloading of shared code
  932. •  needs to reduce system overhead to the minimum amount
  933. •  needs transparent access to per-context global data
  934. •  DOES NOT need system-level OOP support
  935.  
  936.  
  937. SOM
  938. - ----------
  939. Apple is in the process of licensing and porting IBM's System's Object
  940. Model (SOM) technology to Macintosh. SOM is a multi-platform standard
  941. providing for system-level sharable objects in a language-neutral way. SOM
  942. also solves the "fragile base class" problem, avoiding the need for client
  943. libraries to be recompiled when the base class they inherit from is in a
  944. different library and is changed.
  945.  
  946. To offer these benefits (multi-platform support and fragile base-class
  947. resolution) SOM requires the use of an IDL as a first step in the
  948. development process.
  949.  
  950. SOM runs on top of CFM, and thus will become available on both 68K and
  951. PowerPC Macintosh.
  952.  
  953. SOM is a foundation technology for OpenDoc. 
  954.  
  955.  
  956. Integration
  957. - ----------
  958. SOM and ASLM will both live in a CFM run-time environment, and will both
  959. be available on both 68K and PowerPC Macintosh. Thus there will be no
  960. impediment to co-existence of ASLM and SOM, or to applications that use
  961. both ASLM and SOM. In fact, a SOM class could easily call an ASLM class or
  962. vice-versa.
  963.  
  964. Over time, some of the functionality provided by ASLM may be supplanted by
  965. SOM. However, ASLM APIs will be preserved. As a result, applications
  966. written to the ASLM API may have some functionality transparently migrated
  967. to SOM in the future.
  968.  
  969. - -----------------------------------------------------------------
  970. Garry Hornbuckle    Product Manager, Communications & Collaboration
  971. - -----------------------------------------------------------------
  972. "If I told you that I   | email      garryh@seeding.apple.com
  973.  spoke only for myself  | applelink  HORNBUCKLE1
  974.  would you believe me?" | fax        (408) 974-1211
  975. - -----------------------------------------------------------------
  976.  
  977. ---------------------------
  978.  
  979. >From Jaeger@fquest.com (Brian Stern)
  980. Subject: Review of PowerMac devtools available
  981. Date: 26 Aug 1994 03:20:05 GMT
  982. Organization: The University of Texas at Austin, Austin, Texas
  983.  
  984. If you haven't come across it yet, there is an interesting article titled: 
  985.  
  986. PUTTING THE C(++) INTO POWER MACINTOSH by Jon Lansdell (August 19th 1994),
  987.  
  988. that has appeared in the current version of powerPC news.  It is the first
  989. part of a two part series that will review the four native development
  990. environments for the PowerMac.  In case you're wondering these are:
  991.  
  992. *Symantec's Cross Development kit*
  993. *MPW*
  994. *The Absoft C/C++ SDK* 
  995. *CodeWarrior *
  996.  
  997. Here are a few quotes taken completely out of context:
  998.  
  999. Symantec's image amongst the Macintosh developer community was somewhat
  1000. tarnished by release 6.0 of Symantec C++ for the Macintosh and reports
  1001. that it was somewhat buggy. 
  1002.  
  1003. MPW - tried, tested and old.  ETO#15 and the MPW Pro CD both contain
  1004. pre-release native versions of the MPW Shell and various tools, including
  1005. PPCC. While this does compile applications around twice as fast, the
  1006. Linker still has to run under emulation, so while Apple work on a new
  1007. native development environment, developers have plenty of time for coffee
  1008. breaks during the build process. 
  1009.  
  1010. The Absoft SDK includes a couple of extras which give it claim to be a
  1011. fully rounded development environment.  Although the Linker and Compiler
  1012. are native, it does cry out to be part of a completely native development
  1013. environment.
  1014.  
  1015. You can find the article via your favorite web-client at:
  1016.  
  1017. http://power.globalnews.com:8000/
  1018.  
  1019. -- 
  1020. Brian  Stern  :-{)}
  1021. Jaeger@fquest.com
  1022.  
  1023. ---------------------------
  1024.  
  1025. >From scotth@jaguar.visix.com (Scott Hofmann)
  1026. Subject: SetDialogDefaultItem() not doing anything!
  1027. Date: Thu, 25 Aug 1994 13:42:32 GMT
  1028. Organization: Visix Software, Reston, Virginia
  1029.  
  1030. In some code I've written for a preferences dialog, I use the calls
  1031. SetDialogDefaultItem() and SetDialogCancelItem() to make my "OK" and "Cancel"
  1032. buttons look and perform according to Apple spec, but both traps aren't doing
  1033. anything- it's like they exist, but are bound to no-op. This happens both in
  1034. Symantec C++ 6.0, using the glue from the THINK Ref 2.0, and in Metrowerks CW4.
  1035. I'm working on a Centris 650 running System 7.1, so I'm pretty sure my ROMs
  1036. contain that trap - could I be mistaken about this? Has anyone use gotten these
  1037. traps to work? Thanks,
  1038.  
  1039.                                                             scott
  1040. -- 
  1041. - -----------------------------------------------------------------------------
  1042. J. Scott Hofmann                        | "You've saved humanity...once again"
  1043. scotth@visix.com                        |       -Q to Capt. Picard, ST:TNG
  1044.  
  1045. +++++++++++++++++++++++++++
  1046.  
  1047. >From hanrek@cts.com (Mark Hanrek)
  1048. Date: 25 Aug 1994 20:18:00 GMT
  1049. Organization: The Information Workshop
  1050.  
  1051. In article <SCOTTH.94Aug25094232@jaguar.visix.com>,
  1052. scotth@jaguar.visix.com (Scott Hofmann) wrote:
  1053.  
  1054. > In some code I've written for a preferences dialog, I use the calls
  1055. > SetDialogDefaultItem() and SetDialogCancelItem() to make my "OK" and "Cancel"
  1056. > buttons look and perform according to Apple spec, but both traps aren't doing
  1057. > anything- it's like they exist, but are bound to no-op. This happens both in
  1058. > Symantec C++ 6.0, using the glue from the THINK Ref 2.0, and in
  1059. Metrowerks CW4.
  1060. > I'm working on a Centris 650 running System 7.1, so I'm pretty sure my ROMs
  1061. > contain that trap - could I be mistaken about this? Has anyone use
  1062. gotten these
  1063. > traps to work? Thanks,
  1064.  
  1065.  
  1066. There is a certain "time" that these calls should be made so that they are
  1067. associated with the current dialog. Otherwise, it could cause problems in
  1068. the cases in which you don't want the system to do its thing for you.  
  1069.  
  1070. In other words, the effect is not global, but rather "contextual". 
  1071. Example source code will show you what you need to know.
  1072.  
  1073. Hope this helps.
  1074.  
  1075. Mark Hanrek
  1076.  
  1077. +++++++++++++++++++++++++++
  1078.  
  1079. >From dirk@gaga.maschinenbau.uni-dortmund.de (Dirk Froehling)
  1080. Date: Fri, 26 Aug 1994 09:41:03 +0100
  1081. Organization: UniDO
  1082.  
  1083. In article <hanrek-2508941320100001@auke.cts.com>, hanrek@cts.com (Mark
  1084. Hanrek) wrote:
  1085.  
  1086. > In article <SCOTTH.94Aug25094232@jaguar.visix.com>,
  1087. > scotth@jaguar.visix.com (Scott Hofmann) wrote:
  1088. > > In some code I've written for a preferences dialog, I use the calls
  1089. > > SetDialogDefaultItem() and SetDialogCancelItem() to make my "OK" and 
  1090. > There is a certain "time" that these calls should be made so that they are
  1091. > associated with the current dialog.
  1092.  
  1093. Try something like (this is Pascal, but...):
  1094.  
  1095.         myDlog := GetNewDialog(myID, nil, pointer(-1));
  1096.  
  1097.         myErr := SetDialogDefaultItem(myDlog, OK);
  1098.         myErr := SetDialogCancelItem(myDlog, cancel);
  1099.  
  1100.      { here it comes: }
  1101.         myErr := GetStdFilterProc(filterIt); { don't use your own filter }
  1102.  
  1103.         repeat
  1104.             ModalDialog(filterIt, itemHit);
  1105.             { do something }
  1106.         until itemHit in [OK, Cancel];
  1107.  
  1108. -- 
  1109. | Dirk Froehling - Germany, Uni Dortmund, FB Maschinenbau, LS Mechanik |
  1110. | dirk@gaga.maschinenbau.uni-dortmund.de            GEnie: D.FROEHLING |
  1111.  
  1112. +++++++++++++++++++++++++++
  1113.  
  1114. >From gbolsinga@aol.com (GBolsinga)
  1115. Date: 26 Aug 1994 16:02:07 -0400
  1116. Organization: America Online, Inc. (1-800-827-6364)
  1117.  
  1118. In article <dirk-260894094103@129.217.230.3>,
  1119. dirk@gaga.maschinenbau.uni-dortmund.de (Dirk Froehling) writes:
  1120.  
  1121. >Try something like (this is Pascal, but...):
  1122. >
  1123. >  myDlog := GetNewDialog(myID, nil, pointer(-1));
  1124. >
  1125. >  myErr := SetDialogDefaultItem(myDlog, OK);
  1126. >  myErr := SetDialogCancelItem(myDlog, cancel);
  1127. >
  1128. >  { here it comes: }
  1129. >  myErr := GetStdFilterProc(filterIt); { don't use your own filter }
  1130. >
  1131. >  repeat
  1132. >   ModalDialog(filterIt, itemHit);
  1133. >   { do something }
  1134. >  until itemHit in [OK, Cancel];
  1135.  
  1136. You could use your own filter which pre-filters the call and then calls
  1137. the 
  1138. standard filter proc
  1139.  
  1140. Greg
  1141. MPI Multimedia
  1142. /* These are MY opinions */
  1143.  
  1144.  
  1145. +++++++++++++++++++++++++++
  1146.  
  1147. >From stk@uropax.contrib.de (Stefan Kurth)
  1148. Date: 27 Aug 1994 18:20:16 +0200
  1149. Organization: Contributed Software GbR
  1150.  
  1151. In article <33lhnv$m7r@search01.news.aol.com>,
  1152. GBolsinga <gbolsinga@aol.com> wrote:
  1153.  
  1154. > In article <dirk-260894094103@129.217.230.3>,
  1155. > dirk@gaga.maschinenbau.uni-dortmund.de (Dirk Froehling) writes:
  1156. >
  1157. > > { don't use your own filter }
  1158. >
  1159. > You could use your own filter which pre-filters the call and then calls
  1160. > the standard filter proc
  1161.  
  1162. Yes, but remember to call it like this:
  1163.  
  1164.     GetStdFilterProc(&theFilterProc);
  1165.  
  1166.     asm {
  1167.         move.l d3, -(a7)
  1168.     }
  1169.  
  1170.     result = theFilterProc(theDialog, &theEvent, &itemHit);
  1171.  
  1172.     asm {
  1173.         move.l (a7)+, d3
  1174.     }
  1175.  
  1176.     return result;
  1177.  
  1178. since the std filter proc trashes d3, which can cause strange things to
  1179. happen to your local variables.
  1180.  
  1181. ________________________________________________________________________
  1182. Stefan Kurth                 Berlin, Germany              stk@contrib.de
  1183.  
  1184. ---------------------------
  1185.  
  1186. >From woody@alumni.caltech.edu (William Edward Woody)
  1187. Subject: Trouble making floating windows work with modeless dialogs
  1188. Date: 26 Aug 1994 06:56:43 GMT
  1189. Organization: California Institute of Technology, Alumni Association
  1190.  
  1191.  
  1192. I'm having a problem making modeless dialogs work with floating windows.
  1193. The problem is with 'IsDialogEvent()' and 'DialogSelect()'.
  1194.  
  1195. When I receive the event from WaitNextEvent(), I first determine if the
  1196. event is for a modal dialog through 'IsDialogEvent()', and if it is,
  1197. I call my subroutine which gets the calls 'DialogSelect()' to process
  1198. the event, and then handle the control ID if DialogSelect returns TRUE.
  1199.  
  1200. The problem is that it seems that the modeless dialog is not being
  1201. processed correctly if there is a floating window up. I think what's
  1202. going on is that as the floating window is the frontmost window in the
  1203. WindowList, IsDialogEvent() and DialogSelect() do not handle mouseDown,
  1204. nullEvent, or keyDown events at all.
  1205.  
  1206. Kludging the system to put the dialog at the head of the WindowList
  1207. global for processing of the IsDialogEvent() and DialogSelect() routines
  1208. allows me to click on buttons, but edit fields are handled completely
  1209. wrong.
  1210.  
  1211. What I want to know is, what can I do to make IsDialogEvent() and
  1212. DialogSelect() work. (I don't want to use the GhostWindow global because
  1213. I may have more than one floating window up at once.) If I can't
  1214. make those routines work, then how can I replace the routines with
  1215. code of my own to handle dialog events?
  1216.  
  1217. I'm really stuck here, and I don't know where to turn. This is my last
  1218. hope.
  1219.  
  1220. advTHANKSance.
  1221.  
  1222.                         - Bill
  1223. -- 
  1224. o William Edward Woody      | "I'm shying from the light
  1225.   In Phase Consulting      |  I always loved the night
  1226.   337 West California #4  |  And now you offer me eternal darkness"
  1227.   Glendale, CA 91203      |          - Depeche Mode, "One Caress"
  1228.  
  1229. +++++++++++++++++++++++++++
  1230.  
  1231. >From woody@alumni.caltech.edu (William Edward Woody)
  1232. Date: 26 Aug 1994 22:19:16 GMT
  1233. Organization: California Institute of Technology, Alumni Association
  1234.  
  1235. a while ago (yesterday?) I wrote:
  1236. > I'm having a problem making modeless dialogs work with floating windows.
  1237. > The problem is with 'IsDialogEvent()' and 'DialogSelect()'.
  1238. > What I want to know is, what can I do to make IsDialogEvent() and
  1239. > DialogSelect() work. (I don't want to use the GhostWindow global because
  1240. > I may have more than one floating window up at once.) If I can't
  1241. > make those routines work, then how can I replace the routines with
  1242. > code of my own to handle dialog events?
  1243.  
  1244. Well, without a solution I could use fast enough, I bit the bullet and wrote
  1245. the routines MIsDialogEvent() and MDialogSelect() to replace IsDialogEvent()
  1246. and DialogSelect() to solve my problem.
  1247.  
  1248. I have attached the code I wrote below, so others can also do modeless
  1249. dialogs and floating windows at the same time.
  1250.  
  1251. NOTE:    In these routines below, MFrontWindow() is the replacement to
  1252.     FrontWindow() which figures out the frontmost non-floater window.
  1253.  
  1254. NOTE:    These routines are not well-tested. They work for me, but they
  1255.     may have bugs (some severe) which prevent their adequate use.
  1256.     Note that they were written to be used together, and are not
  1257.     compatable with their 'IsDialogEvent()/DialogSelect()' counterparts.
  1258.     I don't know why this is; it just is.
  1259.  
  1260. Code follows:
  1261.  
  1262. - -CUT HERE---CUT HERE---CUT HERE---CUT HERE---CUT HERE---CUT HERE---
  1263.  
  1264. /*  MIsDialogEvent
  1265.  *
  1266.  *    Is this an event for this dialog box?
  1267.  */
  1268.  
  1269. Boolean MIsDialogEvent(EventRecord *event)
  1270. {
  1271.     WindowPtr w;
  1272.     short where;
  1273.     
  1274.     switch (event->what) {
  1275.     case mouseDown:
  1276.         where = FindWindow(event->where,&w);
  1277.         if (where != inContent) w = NULL;
  1278.         else if (w != MFrontWindow()) w = NULL;
  1279.         break;
  1280.     case updateEvt:
  1281.     case activateEvt:
  1282.         w = (WindowPtr)(event->message);
  1283.         break;
  1284.     case keyDown:
  1285.     case autoKey:
  1286.     default:
  1287.         w = MFrontWindow();
  1288.         break;
  1289.     }
  1290.     if (w == NULL) return 0;
  1291.     if (((WindowPeek)w)->windowKind == dialogKind) return 1;
  1292.     return 0;
  1293. }
  1294.  
  1295. /*  MDialogSelect
  1296.  *
  1297.  *    Do the dialog select routines. This does all of the dialog
  1298.  *  processing stuff for this dialog window if it is one.
  1299.  */
  1300.  
  1301. Boolean MDialogSelect(EventRecord *event, DialogPtr *dlog, short *item)
  1302. {
  1303.     WindowPtr w;
  1304.     DialogPeek peek;
  1305.     short where;
  1306.     Handle h;
  1307.     Rect r;
  1308.     TEHandle text;
  1309.     char c;
  1310.     short index;
  1311.     short length;
  1312.     Point pt;
  1313.     long tmp;
  1314.     
  1315.     /*
  1316.      *  Determine the dialog window that is being used here.
  1317.      */
  1318.     
  1319.     switch (event->what) {
  1320.         case mouseDown:
  1321.         case mouseUp:
  1322.             where = FindWindow(event->where,&w);
  1323.             if (where != inContent) w = NULL;
  1324.             break;
  1325.         case updateEvt:
  1326.         case activateEvt:
  1327.             w = (WindowPtr)(event->message);
  1328.             break;
  1329.         default:
  1330.             w = MFrontWindow();
  1331.             break;
  1332.     }
  1333.     if (w == NULL) return 1;        // Not my event...
  1334.     if (((WindowPeek)w)->windowKind != dialogKind) return 1;
  1335.     
  1336.     /*
  1337.      *  Now, actually do this event as appropriate
  1338.      */
  1339.     
  1340.     *dlog = w;                // The dialog I was handling.
  1341.     *item = 0;                // Default item (0)
  1342.     peek = (DialogPeek)w;        // So I can get at internal stuff
  1343.     switch (event->what) {
  1344.     
  1345.         /*
  1346.          *  Activate/Deactivate
  1347.          *
  1348.          *    This activates or deactivates the text edit field
  1349.          *  if it is present in the dialog box.
  1350.          */
  1351.         
  1352.         case activateEvt:
  1353.             SetPort(w);
  1354.             text = peek->textH;
  1355.             if (text) {
  1356.                 if (event->modifiers & activeFlag) {
  1357.                     TEActivate(text);
  1358.                 } else {
  1359.                     TEDeactivate(text);
  1360.                 }
  1361.             }
  1362.             return 0;            // Further processing not needed
  1363.         
  1364.         /*
  1365.          *  Update
  1366.          *
  1367.          *    This simply draws the contents of this thing
  1368.          */
  1369.         
  1370.         case updateEvt:
  1371.             SetPort(w);
  1372.             BeginUpdate(w);
  1373.             UpdateDialog(w,w->visRgn);
  1374.             EndUpdate(w);
  1375.             return 0;            // Further processing not needed
  1376.         
  1377.         /*
  1378.          *  Null event processing
  1379.          *
  1380.          *    Blink the cursor
  1381.          */
  1382.         
  1383.         default:
  1384.         case nullEvent:
  1385.             SetPort(w);
  1386.             if (peek->textH) TEIdle(peek->textH);
  1387.             return 0;            // Further processing not needed
  1388.         
  1389.         /*
  1390.          *  Key events
  1391.          *
  1392.          *    This handles keyboard events by processing the enter/
  1393.          *  escape keys as buttons 1 and 2; otherwise, pass to the
  1394.          *  current edit box, if any.
  1395.          */
  1396.         
  1397.         case keyDown:
  1398.         case autoKey:
  1399.             SetPort(w);
  1400.             c = (unsigned char)(event->message & charCodeMask);
  1401.             
  1402.             /*
  1403.              *  Enter, escape processing
  1404.              */
  1405.             
  1406.             if ((c == 0x03) || (c == 0x0D) || (c == 0x1B)) {                
  1407.                 if ((c == 0x03) || (c == 0x0D)) {
  1408.                     *item = 1;
  1409.                 } else {
  1410.                     *item = 2;
  1411.                 }
  1412.                 
  1413.                 GetDialogItem(w,*item,&where,&h,&r);
  1414.                 HiliteControl((ControlHandle)h,inButton);
  1415.                 Delay(5,&tmp);
  1416.                 HiliteControl((ControlHandle)h,0);
  1417.                 return 1;        // Further processing needed
  1418.             }
  1419.             
  1420.             /*
  1421.              *  Tab processing
  1422.              */
  1423.             
  1424.             if (c == 0x09) {        // Horizontal tab key
  1425.                 if (peek->textH == NULL) return 0;    // Can't deal with it.
  1426.                 length = *((short *)(*(peek->items))) + 1;
  1427.                 index = peek->editField+2;        // Skip this one
  1428.                 
  1429.                 /*
  1430.                  *  Find the next edit item and select it
  1431.                  */
  1432.                 
  1433.                 while (index <= length) {
  1434.                     GetDialogItem(w,index,&where,&h,&r);
  1435.                     if ((0x7F & where) == 16) {        // This is an edit item
  1436.                         SelIText(w,index,0,32767);    // Move edit, select me
  1437.                         *item = index;
  1438.                         return ((where & 0x80) == 0) ? 1 : 0;
  1439.                     }
  1440.                     index++;
  1441.                 }
  1442.                 index = 1;                // Wrap to beginning
  1443.                 while (index <= length) {
  1444.                     GetDialogItem(w,index,&where,&h,&r);
  1445.                     if ((0x7F & where) == 16) {        // This is an edit item
  1446.                         SelIText(w,index,0,32767);    // Move edit, select me
  1447.                         *item = index;
  1448.                         return ((where & 0x80) == 0) ? 1 : 0;
  1449.                     }
  1450.                     index++;
  1451.                 }
  1452.                 *item = 0;
  1453.                 return 0;                // Huh? Dunno...
  1454.             }
  1455.             
  1456.             /*
  1457.              *  Normal keyboard processing
  1458.              */
  1459.             
  1460.             text = peek->textH;
  1461.             if (text == NULL) return 0;            // No edit item to do
  1462.             
  1463.             *item = peek->editField+1;            // Item ID we're doing
  1464.             TEKey(c,text);                // Do character process
  1465.             
  1466.             GetDialogItem(w,*item,&where,&h,&r);    // Return appropriate
  1467.             return ((where & 0x80) == 0) ? 1 : 0;    // for enable flag
  1468.         
  1469.         /*
  1470.          *  Mouse down:
  1471.          *
  1472.          *    track the controls or the edit fields as appropriate
  1473.          */
  1474.         
  1475.         case mouseDown:
  1476.             SetPort(w);
  1477.             pt = event->where;
  1478.             GlobalToLocal(&pt);
  1479.             
  1480.             /*
  1481.              *  Determine where the mouse went down
  1482.              */
  1483.             
  1484.             index = FindDItem(w,pt)+1;
  1485.             if (index == 0) return 0;        // Not on anything
  1486.             GetDialogItem(w,index,&where,&h,&r);
  1487.             *item = index;
  1488.             
  1489.             /*
  1490.              *  Handle inactive objects
  1491.              */
  1492.             
  1493.             if (where & 0x80) {
  1494.                 if (where == 0x90) {        // Edit item here.
  1495.                 
  1496.                     /*
  1497.                      *  Handle edit selection even if inactive
  1498.                      */
  1499.                     
  1500.                     if (peek->editField + 1 != index) {
  1501.                         SelIText(w,index,0,32767);
  1502.                     }
  1503.                     TEClick(pt,(event->modifiers & shiftKey) ? 1 : 
  1504. 0,peek->textH);
  1505.                 }
  1506.                 return 0;
  1507.             }
  1508.             
  1509.             /*
  1510.              *  Process according to where I'm at
  1511.              */
  1512.             
  1513.             switch (where) {
  1514.                 default:
  1515.                     return 1;            // Just return the ID.
  1516.                 case 4:
  1517.                 case 5:
  1518.                 case 6:
  1519.                 case 7:
  1520.                     /*
  1521.                      *  Click on a standard control object
  1522.                      */
  1523.                     
  1524.                     if (TrackControl((ControlHandle)h,pt,NULL)) return 1; // do 
  1525. it.
  1526.                     return 0;            // don't do it.
  1527.                 case 16:            // Handle edit box
  1528.                     if (peek->editField + 1 != index) {
  1529.                         SelIText(w,index,0,32767);
  1530.                     }
  1531.                     TEClick(pt,(event->modifiers & shiftKey) ? 1 : 
  1532. 0,peek->textH);
  1533.                     return 1;            // Return where I am now. 
  1534.             }
  1535.     }
  1536.     return 0;        // Not one of these; can't deal with it at all...
  1537. }
  1538.  
  1539. - -CUT HERE---CUT HERE---CUT HERE---CUT HERE---CUT HERE---CUT HERE---
  1540.  
  1541. I hope this helps. Permission is granted to use this message and the
  1542. code contained herein in any way you want, redistribute it, fold it,
  1543. spindle it, or mutulate it, so long as you don't sue me if the code
  1544. crashes. Given away as is, without warranty of any kind. If you don't
  1545. like this, my lawyer can mud-wrestle your lawyer in the nude for 15
  1546. rounds at the local mud-wrestling bar for brownies. (This assumes,
  1547. of course, that your lawyer and my lawyer look good in the nude. :-)
  1548.  
  1549.                         - Bill
  1550. -- 
  1551. o William Edward Woody      | "I'm shying from the light
  1552.   In Phase Consulting      |  I always loved the night
  1553.   337 West California #4  |  And now you offer me eternal darkness"
  1554.   Glendale, CA 91203      |          - Depeche Mode, "One Caress"
  1555.  
  1556. ---------------------------
  1557.  
  1558. End of C.S.M.P. Digest
  1559. **********************
  1560.  
  1561.  
  1562.  
  1563.